#include "linklist.h"

typedef struct Link{
    uint8_t  elem;
    struct Link *next;
}link,*NodeList;
uint8_t rxbuffer[5]={0,1,2,3,4};
uint8_t data_con[15]={0};
link * initLink(uint8_t data[]);
//链表插入的函数，p是链表，elem是插入的结点的数据域，add是插入的位置
link * insertElem(link * p,uint8_t elem,int add);
//删除结点的函数，p代表操作链表，add代表删除节点的位置
link * delElem(link * p,int add);
//查找结点的函数，elem为目标结点的数据域的值
int selectElem(link * p,uint8_t elem);
//更新结点的函数，newElem为新的数据域的值
link *amendElem(link * p,int add,int newElem);
void display(link *p);
link * disposal_LinkList(link *headNode);
link * insert_list_last(link *head, uint8_t data);
void list_conver_to_arr(link *node, uint8_t *data_arr);

int linklist_test_main(void) {
    //初始化链表（1，2，3，4）
    // printf("初始化链表为：\n");
    link *p=initLink(rxbuffer);
    display(p);
   
    // printf("在第4的位置插入元素5：\n");
    p=insertElem(p, 5, 4);
    display(p);
    //  printf("最后一位插入元素8：\n");
    for(uint8_t i = 0;i< 5;i++)
     p = insert_list_last(p,8);
     display(p);
    // printf("删除元素3:\n");
    p=delElem(p, 3);
    display(p);
   
    // printf("查找元素2的位置为：\n");
    int address=selectElem(p, 2);
    if (address==-1) {
        // printf("没有该元素");
    }else{
        // printf("元素2的位置为：%d\n",address);
    }
    // printf("更改第3的位置的数据为7:\n");
    p=amendElem(p, 3, 7);
    display(p);
   list_conver_to_arr(p,data_con);
   for(uint8_t i =0;i< 15;i++)
   printf("data_con[%d]=%d:\n",i,data_con[i]);
   p = disposal_LinkList(p);
   printf("销毁链表成功:\n");
   display(p);
    return 0;
}
// 创建——插入数据     uint8_t data:插入的数据类型
link * insert_list_last(link *head, uint8_t data)
{
    link * temp=head;//创建临时结点temp
  //只要temp指针指向的结点的next不是Null，就执行输出语句。
    while (temp->next) {
        temp=temp->next;
    }
	// 初始化一个新的结点，准备进行链接
    //创建插入结点c
    link * c=(link*)malloc(sizeof(link));
    c->elem=data;
    //向链表中插入结点
    c->next=temp->next;
    temp->next=c;
    return  head;

}
link * initLink(uint8_t data[]){
    link * p=(link*)malloc(sizeof(link));//创建一个头结点
    link * temp=p;//声明一个指针指向头结点，用于遍历链表
    //生成链表
    for (int i=0; i<5; i++) {
        link *a=(link*)malloc(sizeof(link));
        a->elem=data[i];
        a->next=NULL;
        temp->next=a;
        temp=temp->next;
    }
    return p;
}
link * insertElem(link * p,uint8_t elem,int add){
    link * temp=p;//创建临时结点temp
    //首先找到要插入位置的上一个结点
    for (int i=1; i<add; i++) {
        if (temp==NULL) {
            printf("插入位置无效\n");
            return p;
        }
        temp=temp->next;
    }
    //创建插入结点c
    link * c=(link*)malloc(sizeof(link));
    c->elem=elem;
    //向链表中插入结点
    c->next=temp->next;
    temp->next=c;
    return  p;
}
link * delElem(link * p,int add){
    link * temp=p;
    //遍历到被删除结点的上一个结点
    for (int i=1; i<add; i++) {
        temp=temp->next;
    }
    link * del=temp->next;//单独设置一个指针指向被删除结点，以防丢失
    temp->next=temp->next->next;//删除某个结点的方法就是更改前一个结点的指针域
    free(del);//手动释放该结点，防止内存泄漏
    return p;
}
int selectElem(link * p,uint8_t elem){
    link * t=p;
    int i=1;
    while (t->next) {
        t=t->next;
        if (t->elem==elem) {
            return i;
        }
        i++;
    }
    return -1;
}
link *amendElem(link * p,int add,int newElem){
    link * temp=p;
    temp=temp->next;//tamp指向首元结点
    //temp指向被删除结点
    for (int i=1; i<add; i++) {
        temp=temp->next;
    }
    temp->elem=newElem;
    return p;
}
void display(link *p){
    link* temp=p;//将temp指针重新指向头结点
    int length =0;
    //只要temp指针指向的结点的next不是Null，就执行输出语句。
    if(p == NULL)
   { printf("length= %d\n",length); return;}
    while (temp->next) {
        length ++;
        temp=temp->next;
        printf("%d",temp->elem);
    }
    printf("\n");
    printf("length= %d\n",length);
}
//销毁链表
link * disposal_LinkList(link *headNode)
{
	if (headNode == NULL)
	return headNode;

	//清空链表,是不清空头节点的，因此从第一个有数据的节点开始释放
	NodeList curNode = headNode->next;
	while (curNode != NULL)
	{
		//先保住下一个节点的位置
		NodeList  nextNode = curNode->next;
		free(curNode);
		curNode = nextNode;	
	}
	//释放头结点
	free(headNode);
	//头结点指针置空
	headNode = NULL;
    return headNode;
}
/**
 * @description: 链表数据转为数组
 * @return {*}
 */
void list_conver_to_arr(link *node, uint8_t *data_arr)
{
	static uint32_t number;
	link *p = node;
	number = 0;
    if(node!= NULL)
    p = p->next;
    else
    return;
	// 遍历头节点到，最后一个数据
	while (p != NULL)
	{

		data_arr[number] = p->elem;
        p = p->next;
		number++;
		
	}
	node = p;
	return;
}